import { QueryKey, useQueryClient } from 'react-query';
import { reorder } from '@src/utils/reorder';
import { Task } from '@src/types/task';

/**
 *
 * @param queryKey 缓存的key
 * @param callback 逻辑处理的回调函数
 * @returns {{previousItems: unknown} | {onError(error: any, newItem: any, context: any): void, onMutate(target: any): Promise<{previousItems: unknown}>, onSuccess: () => Promise<void>}}
 */
export const useConfig = (queryKey: QueryKey, callback: (target: any, old?: any[]) => any[]) => {
  //
  const queryClient = useQueryClient();

  return {
    //成功时,通过queryKey 更新缓存
    onSuccess: () => queryClient.invalidateQueries(queryKey),
    // 当前数据
    async onMutate(target: any) {
      //执行时先更新最新数据,这时接口还没有交互完成
      const previousItems = queryClient.getQueryData(queryKey);
      //
      queryClient.setQueryData(queryKey, (old?: any[]) => {
        return callback(target, old);
      });
      return { previousItems };
    },
    // 当发生错误时
    onError(error: any, newItem: any, context: any) {
      // 更新回原来的数据
      queryClient.setQueryData(queryKey, context.previousItems);
    },
  };
};

/**
 *  =========================  删除  ==========================
 * @param queryKey
 */
export const useDeleteConfig = (queryKey: QueryKey) =>
  useConfig(queryKey, (target, old) => old?.filter((item) => item.id !== target.id) || []);

/**
 *  =========================  修改  ==========================
 * @param queryKey
 */
export const useEditConfig = (queryKey: QueryKey) =>
  useConfig(
    queryKey,
    (target, old) => old?.map((item) => (item.id === target.id ? { ...item, ...target } : item)) || []
  );
/**
 * =========================  添加  ==========================
 * @param queryKey
 */
export const useAddConfig = (queryKey: QueryKey) => useConfig(queryKey, (target, old) => (old ? [...old, target] : []));

/**
 * =========================  看板 重新排序  ==========================
 * @param queryKey
 */
export const useReorderKanbanConfig = (queryKey: QueryKey) =>
  useConfig(queryKey, (target, old) => reorder({ list: old, ...target }));

/**
 * =========================  任务 重新排序  ==========================
 * @param queryKey
 */
export const useReorderTaskConfig = (queryKey: QueryKey) =>
  useConfig(queryKey, (target, old) => {
    const orderedList = reorder({ list: old, ...target }) as Task[];
    return orderedList.map((item) => (item.id === target.fromId ? { ...item, kanbanId: target.toKanbanId } : item));
  });
